package com.stark.commons.spring.web.interceptor;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;

/**
 * feign 请求头拦截器。
 * <p>将 controller 中的请求头复制到 feign 。
 * @author Ben
 * @since 1.0.0
 * @version 1.0.0
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FeignHeadersInterceptor implements RequestInterceptor {

	private String[] headersInclude;

	@Override
	public void apply(RequestTemplate template) {
		if (ArrayUtils.isNotEmpty(headersInclude)) {
			RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
			if (requestAttributes != null) {
				HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
				Enumeration<String> headerNames = request.getHeaderNames();
				if (headerNames != null) {
					while (headerNames.hasMoreElements()) {
						String header = headerNames.nextElement();
						if (include(header)) {
							Enumeration<String> values = request.getHeaders(header);
							while (values.hasMoreElements()) {
								String value = values.nextElement();
								template.header(header, value);
							}
						}
					}
				}
				if (include(HttpHeaders.AUTHORIZATION)
						&& StringUtils.isBlank(request.getHeader(HttpHeaders.AUTHORIZATION))) {
					String token = request.getParameter(OAuth2AccessToken.ACCESS_TOKEN);
					if (StringUtils.isNotBlank(token)) {
						template.header(HttpHeaders.AUTHORIZATION, OAuth2AccessToken.BEARER_TYPE + " " + token);
					}
				}
			}
		}
	}

	private boolean include(String header) {
		for (String _header : headersInclude) {
			if (_header.equalsIgnoreCase(header)) {
				return true;
			}
		}
		return false;
	}

}
